home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
asmutil
/
asm_n_z.zip
/
NEWINIT.ASM
< prev
next >
Wrap
Assembly Source File
|
1987-05-05
|
18KB
|
574 lines
title newinit.asm
comment |--------------------------------------------------------------
In text modes the active page can be switched between 1-4 (80-col) or
1-8 (40-col) by pressing ALT and the corresponding # on the TOP ROW. This
feature can only be used to view the other pages. Results of all CON I/O
while paging are unpredictable and messy.
As protection against duplicate installation, INT 15h with AX = X'FF00'
returns AX = X'ABCD'.
The keypad "5" key will toggle processing. While paused, a flashing,
highlighted "P" will appear in the lower-right corner (not graphics).
If Numlock is on, shift-"5" is required. If Alt or Ctrl are pressed, nothing
changes. Scroll Lock, Caps Lock, and Ins are irrelevant.
This program sets the video mode to 80 col monochrome.
The enhanced keyboard can be toggled on/off with Alt-PrtSc, and a 1/8 sec
2000 Hz tone will sound when toggled on. (The PrtSc modification cannot
be turned off.)
NOTE: If both shift keys are depressed at installation time, the
installation will be cancelled, with errorlevel set to X'AB'.
------------------------------------------------------------------------|
bios_data segment at 0040h
org 17h
kb_flag db ? ; keyboard status byte
kb_flag_1 db ?
org 49h
v_mode db ? ; BIOS video mode
v_width db ? ; BIOS screen width
org 62h
v_page db ? ; BIOS video page
mystery_w dw ? ; word used by pause routine
mystery_b db ? ; byte used by pause routine
bios_data ends
cseg segment
assume cs:cseg
org 80h
parm_cnt db ? ; parameter count
parm_data db ? ; start of parameter data space
org 100h ; .COM file
begin: jmp init_vectors ; initialize and attach to DOS
; addresses of video and keyboard I/O ROM routines
prtsc dd 0 ; INT 5
kybd dd 0 ; INT 9
cass dd 0 ; INT 15h
kybd_io dd 0 ; INT 16h
; constants and segments
bios_dat dw 40h ; bios_data segment
mono_seg dw 0b000h ; segment of MGA
color_seg dw 0b800h ; segment of CGA
datatbl db 2,3,0,1,6,4,5 ; scan-code to video mode data
indicator equ "P"+256*10001111b ; an highlighted, flashing "P"
row equ 24 ; position of indicator for mono moniter
col equ 79
mono_point equ 2*((row*80)+col) ; offset in mono segment
; variable data
vdata db 0 ; current video mode or page
code_seg dw 0 ; CS of resident routines
graph_bit db 0 ; flag to signal graphics mode
toggle db 1 ; enables/disables enhanced keyboard
prtsc_int: sti ; enable interrupts
push ax ; save regs
push dx
mov ah,2 ; read printer status
xor dx,dx ; zero DX - LPT1
int 17h ; printer I/O
xor ah,30h ; check for OFFLINE
jnz chk_shft ; skip beep, prepare for exit
pop dx
no_dump: pop ax
iret
chk_shft: pop dx
push ds
mov ds,bios_dat ; set DS = X'40'
assume ds:bios_data
test kb_flag,00000010b ; check for LEFT shift key
pop ds ; restore regs
jz no_dump ; skip screen dump if no LEFT shift
pop ax
jmp prtsc ; print screen routine
calculate: assume ds:bios_data
xor ax,ax ; zero AX
xor cx,cx ; likewise
mov al,v_width ; AX = 00 width
mov cl,v_page ; save for later multiply
mov bx,25 ; calculate offset into page
mul bl
dec ax ; = (25*width)-1
shl ax,1 ; MUL AX,2 - skip attribute bytes
mov bx,ax ; save in BX
mov ax,2048 ; byte length of 40 column page
cmp v_width,40 ; check for 40 column screen
je multiply ; if yes, leave AX alone
shl ax,1 ; if no, change to 80 column offset
multiply: mul cx ; multiply by page number
add bx,ax ; sum buffer offset with page offset
mov es,color_seg ; load ES with CGA segment
assume es:nothing
skip_cga: mov cx,es:[bx] ; save screen data in CX
mov word ptr es:[bx],indicator ; store flashing "P" on screen
rejoin: ; branch made if graphics mode - skip indicator
mov dx,mystery_w ; load mystery word
add dx,4 ; more mysterious code
mov al,mystery_b ; load mystery byte
out dx,al ; I have no clue what this does
call reset
or kb_flag_1,00001000b ; turn ctrl-num-lock on
sti ; enable interrupts
again: test kb_flag_1,00001000b ; check if ctrl-num-lock on
jnz again ; if on, check again
cli ; disable interrupts (play it safe)
test graph_bit,1 ; check if graphics mode
mov graph_bit,0 ; reset graphics flag
jnz skip_mov ; skip restoration of screen data
mov es:[bx],cx ; restore screen data
skip_mov: pop es ; restore regs
pop dx
pop cx
pop bx
pop ds
pop ax
iret
pause: assume ds:bios_data ; DS set in FIVE: routine
push bx ; save BX (for active page)
push cx ; save CX to use as scratch register
push dx
push es
cmp v_mode,4 ; check for text mode
jb calculate ; continue if yes
cmp v_mode,7 ; check for monochrome buffer
jne no_p ; skip "P" if graphics
mov es,cs:mono_seg ; point ES to segment at 0b000h
mov bx,mono_point ; offset into monochrome segment
jmp short skip_cga ; skip color setup
no_p: mov graph_bit,1 ; set graphics mode flag
jmp short rejoin ; rejoin main code
yes: and kb_flag_1,11110111b ; turn ctrl-num-lock off
call reset ; reset keyboard
pop ds
pop ax
iret
assume ds:nothing
five: push ds ; save data segment
mov ds,cs:bios_dat ; point to keyboard data
assume ds:bios_data
test kb_flag_1,00001000b ; check if Ctrl-NumLock on
jnz yes ; if yes, unpause
mov al,kb_flag ; get shift key status byte
test al,00001100b ; check for Alt or Ctrl pressed
jnz quit ; exit if so
and al,00100011b ; isolate NumLock and Shift bits
jz pause ; if zero (none pressed) then go!
cmp al,00100000b
ja pause ; both NumLock & Shift must be pressed
; if not, then end
assume ds:nothing
quit: pop ds ; restore regs
pop ax
jmp kybd ; goto BIOS
assume ds:nothing
; intercepts INT 9
kybd_int: push ax ; save reg
in al,60h ; get scan code
cmp al,37h ; scan code of PrtSc key
je tog_chk ; check for Alt pressed before toggling
test toggle,1 ; check if enhanced keyboard enabled
jz off ; if not, skip enhanced processing
cmp al,4ch ; scan code of keypad "5" ?
je five ; if yes, check further
cmp al,46h ; check for Scroll-Lock (Break) key
je break ; if so, look for Ctrl-Shift
off: pop ax ; if not, restore reg and
jmp kybd ; goto BIOS
; check for right-shift-Ctrl
break: push ds ; save reg
mov ds,bios_dat ; set DS to bios data segment
assume ds:bios_data
test kb_flag_1,00001000b ; check if ctrl-num-lock on
jnz quit ; goto BIOS if yes
test kb_flag,00000001b ; right shift key pressed?
jz quit
test kb_flag,00000100b ; check for Ctrl key pressed
jz quit
call reset
mov ax,4ccah ; DOS EXIT function 4C
; ErrorLevel = 202
int 21h
pop ds ; restore regs
pop ax
iret ; return from key interrupt
tog_chk: push ds ; save DS
mov ds,bios_dat ; point DS to bios data segment
assume ds:bios_data
test kb_flag_1,00001000b ; check for Ctrl-NumLock pause on
jnz quit ; goto BIOS if yes
test kb_flag,00000111b ; check for Ctrl or L/R shift pressed
jnz quit ; don't toggle if yes - send key to bios
test kb_flag,00001000b ; check for Alt pressed
jz quit ; don't toggle if no - send key to bios
xor toggle,1 ; toggle
jz skip_beep ; skip beep if toggled off
push cx ; save count reg for delay
; beep
; Step 1 -- prepare the timer to receive its divisor
mov al,0b6h ; timer mode register signal
out 67,al ; output to timer control port
; Step 2 -- send the divisor count to the timer
; Divisor = (1,190,000 / desired frequency)
mov ax,595 ; divisor for 2000 Hz
out 66,al ; output low-order byte of divisor
mov al,ah ; high-order byte to output reg
out 66,al ; output high-order byte of divisor
; Step 3 -- turn on the two bits which activate the speaker, and the
; timer's control of the speaker
in al,97 ; get current bit settings - port 97
mov ah,al ; save port 97 to turn sound off
or al,03 ; turn on last two bits
out 97,al ; send back the new value
mov cx,8000h ; approx 1/8 second
delay: loop delay ; sounding tone while counting
mov al,ah ; restore original port 97
out 97,al ; stop tone
pop cx ; restore count reg
skip_beep: call reset ; reset kybd and interrupt controller
pop ds ; restore regs